package cn.qn.common.configs;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

/**
 * @author: Bryant
 * @date: 2019/1/29
 * @description:
 */
@Aspect
@Component
@Slf4j
public class HttpAspect {

    /**
     * 这样写是将重复的代码提取出来方便处理
     */
    @Pointcut("execution(public * tt.dz.app.controller.*.*(..))")
    public void log() {
    }

    /**
     * @param joinPoint 注意：该方法中的HttpServletRequest为javax.servlet.http.HttpServletRequest;
     */
    @Before("log()")
    public void doBefore(JoinPoint joinPoint) {

       ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        JSONObject logs=new JSONObject();
        logs.put("class",joinPoint.getSignature().getDeclaringTypeName());
        logs.put("method",joinPoint.getSignature().getName());
        logs.put("ip",request.getRemoteAddr());
        logs.put("token",request.getHeader("authorization"));

        Object[] args = joinPoint.getArgs();
        Object[] arguments  = new Object[args.length];
        for (int i = 0; i < args.length; i++) {
            if (args[i] instanceof ServletRequest || args[i] instanceof ServletResponse || args[i] instanceof MultipartFile) {
                //ServletRequest不能序列化，从入参里排除，否则报异常：java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false)
                //ServletResponse不能序列化 从入参里排除，否则报异常：java.lang.IllegalStateException: getOutputStream() has already been called for this response
                continue;
            }
            arguments[i] = args[i];
        }
        if (arguments != null) {
            try {
                logs.put("args",arguments);
            } catch (Exception e) {
                logs.put("args",arguments.toString());
            }
        }
        log.info(JSONObject.toJSONString(logs));
    }

    @After("log()")
    public void doAfter() {

    }

    @AfterReturning(returning = "obj", pointcut = "log()")
    public void doAfterReturning(Object obj) {
        log.info(JSONObject.toJSONString(obj));
    }


}

